home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
ACORNUSERS
/
EMULATOR
/
MAGICKIT
/
assembler
/
c
/
macro
< prev
next >
Wrap
Text File
|
1998-04-14
|
4KB
|
243 lines
#include <stdio.h>
#include <string.h>
#include "defs.h"
#include "externs.h"
int mopt;
int in_macro;
int expand_macro;
char marg[8][10][80];
int midx;
int mcounter, mcntmax;
int mcntstack[8];
struct t_line *mstack[8];
struct t_line *mlptr;
struct t_macro *macro_tbl[256];
struct t_macro *mptr;
/* .macro pseudo */
do_macro(int *ip)
{
if (pass == LAST_PASS)
println();
else {
if (expand_macro) {
error("Can not nest macro definitions!");
return;
}
if (lablptr == NULL) {
error("No name for the macro!");
return;
}
if (!stremove())
return;
if (!check_eol(ip))
return;
if (!macro_install())
return;
}
in_macro = 1;
}
/* .endm pseudo */
do_endm(int *ip)
{
error("Unexpected ENDM!");
return;
}
/* search for a macro */
macro_look(int idx)
{
char name[32];
char c;
int hash;
int i;
i = 0;
hash = 0;
while(c = prlnbuf[idx]) {
if (c == ' ' || c == '\t' || c == ';')
break;
if (!isalnum(c) && c != '_')
return (0);
if (isdigit(c) && i == 0)
return (0);
name[i++] = c;
hash += c;
hash = (hash << 3) + (hash >> 5) + c;
idx++;
if (i > 31)
return (0);
}
name[i] = '\0';
hash &= 0xFF;
mptr = macro_tbl[hash];
while (mptr) {
if (!strcmp(name, mptr->name))
break;
mptr = mptr->next;
}
if (mptr)
return (macro_extract(idx));
else
return (0);
}
/* extract macro arguments */
macro_extract(int idx)
{
char *ptr;
char c, t;
int i, j, f, arg;
if (midx == 7) {
error("Too many nested macro calls!");
return (-1);
}
mcntstack[midx] = mcounter;
mstack[midx++] = mlptr;
arg = 0;
ptr = marg[midx][0];
for (i = 0; i < 9; i++) {
*ptr = '\0';
ptr += 80;
}
ptr = marg[midx][0];
for (;;) {
while (c = prlnbuf[idx]) {
if (c != ' ' && c != '\t')
break;
idx++;
}
switch (c) {
case ',':
arg++;
idx++;
ptr += 80;
if (arg == 9) {
error("Too many arguments for a macro!");
return (-1);
}
break;
case '{':
idx++;
case '\"':
i = 0;
if (c == '{')
t = '}';
else
t = '\"';
while (c = prlnbuf[idx]) {
ptr[i++] = c;
if (i == 80) {
error("Invalid macro argument length!");
return (-1);
}
if (c == t)
break;
idx++;
}
switch (c) {
case '\0':
error("Unterminated ASCII string!");
return (-1);
case '}':
i--;
break;
}
while (c = prlnbuf[++idx]) {
if (c != ' ' && c != '\t')
break;
}
if (c != ',' && c != ';') {
error("Syntax error!");
return (-1);
}
ptr[i] = '\0';
break;
case ';':
case '\0':
return (1);
default:
i = 0;
j = 0;
f = 0;
while (c = prlnbuf[idx]) {
if (c == ',' || c == ';')
break;
if (f) {
if (c != ' ') {
for (;i < j; i++)
ptr[i++] = ' ';
ptr[i++] = c;
f = 0;
}
}
else if (c == ' ')
f = 1;
else
ptr[i++] = c;
if (i == 80) {
error("Invalid macro argument length!");
return (-1);
}
idx++;
j++;
}
ptr[i] = '\0';
break;
}
}
}
/* install a macro in the hash table */
macro_install()
{
char c;
int hash;
int i;
hash = 0;
for (i = 1; i <= symbol[0]; i ++) {
c = symbol[i];
if (!isalnum(c) && c != '_') {
error("Invalid macro name!");
return (0);
}
hash += c;
hash = (hash << 3) + (hash >> 5) + c;
}
hash &= 0xFF;
mptr = macro_tbl[hash];
while (mptr) {
if (!strcmp(mptr->name, &symbol[1]))
break;
mptr = mptr->next;
}
if (mptr) {
error("Macro defined twice!");
return (0);
}
if ((mptr = (void *)malloc(sizeof(struct t_macro))) == NULL) {
error("Out of memory!");
return (0);
}
strcpy(mptr->name, &symbol[1]);
mptr->line = NULL;
mptr->next = macro_tbl[hash];
macro_tbl[hash] = mptr;
mlptr = NULL;
return (1);
}